function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }

function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

import React, { useState, useEffect, useRef } from 'react';
import Lane from './components/Lane';
import List from './components/List';
import CreateNode from './components/CreateNode';
import ActionButtons from './components/ActionButtons';
import { Spin } from 'antd';
import { usePersistFn, useInterval, useDebounceEffect } from 'ahooks';
import useHooks from './useHooks';
import { getGraphData, nextTick, createGraphNodeData, getLabelText, dbHelper, autoSaveJson } from './tools';
import defaultData from './defaultData';
import './components/assets/font/iconfont';
import 'antd/dist/antd.css';
import defaultAssets from './components/assets';
import './style/index';
window._globalAssets = defaultAssets;

const ArchDesign = function ArchDesign({
  assets,
  moduleConfig,
  data,
  onAddLink,
  onRemoveLink,
  onRemoveNode,
  onCreateNode,
  onUpdateNode,
  onUndoOrRedo,
  onSave,
  saveInterval = 10000
}) {
  window._saveInterval = saveInterval;
  const archWrapper = useRef(null);

  const _useState = useState(),
        _useState2 = _slicedToArray(_useState, 2),
        graph = _useState2[0],
        setGraph = _useState2[1];

  const _useState3 = useState(false),
        _useState4 = _slicedToArray(_useState3, 2),
        visible = _useState4[0],
        setVisible = _useState4[1];

  const _useState5 = useState(true),
        _useState6 = _slicedToArray(_useState5, 2),
        initLoading = _useState6[0],
        setInitLoading = _useState6[1];

  const _useState7 = useState(false),
        _useState8 = _slicedToArray(_useState7, 2),
        canRedo = _useState8[0],
        setCanRedo = _useState8[1];

  const _useState9 = useState(false),
        _useState10 = _slicedToArray(_useState9, 2),
        canUndo = _useState10[0],
        setCanUndo = _useState10[1];

  const _useState11 = useState(),
        _useState12 = _slicedToArray(_useState11, 2),
        currentCell = _useState12[0],
        setCurrentCell = _useState12[1];

  const _useState13 = useState([]),
        _useState14 = _slicedToArray(_useState13, 2),
        laneOptions = _useState14[0],
        setLaneOptions = _useState14[1];

  const _useState15 = useState(defaultData),
        _useState16 = _slicedToArray(_useState15, 2),
        graphData = _useState16[0],
        setGraphData = _useState16[1];

  const _useState17 = useState(window._globalAssets),
        _useState18 = _slicedToArray(_useState17, 2),
        assetsData = _useState18[0],
        setAssetsData = _useState18[1];

  const _useState19 = useState(1),
        _useState20 = _slicedToArray(_useState19, 2),
        zoom = _useState20[0],
        setZoom = _useState20[1]; // 全屏显示


  const _useState21 = useState(false),
        _useState22 = _slicedToArray(_useState21, 2),
        isFullScreen = _useState22[0],
        setIsFullScreen = _useState22[1]; // 初始化数据
  // 从 indexdb 中恢复数据


  const restoreData = usePersistFn( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
    var store, _ref2, storeId, updateTime, expired, storeData, nodeDatas;

    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) switch (_context.prev = _context.next) {
        case 0:
          setInitLoading(true);
          _context.next = 3;
          return dbHelper.ready();

        case 3:
          _context.next = 5;
          return dbHelper.findByPk('graphDatas', '1');

        case 5:
          store = _context.sent;
          _ref2 = store || {}, storeId = _ref2.id, updateTime = _ref2.updateTime, expired = _ref2.expired, storeData = _ref2.data;
          nodeDatas = data;

          if (storeId && updateTime + expired > Date.now()) {
            if (storeData) nodeDatas = storeData;
          }

          setLaneOptions(nodeDatas.lanes.map(({
            id,
            name
          }) => ({
            label: name,
            value: id
          })));
          setGraphData(getGraphData(nodeDatas));
          setInitLoading(false);
          _context.next = 14;
          return autoSaveJson(null, graph);

        case 14:
        case "end":
          return _context.stop();
      }
    }, _callee);
  }))); // 自动保存

  useInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
    return regeneratorRuntime.wrap(function _callee2$(_context2) {
      while (1) switch (_context2.prev = _context2.next) {
        case 0:
          _context2.next = 2;
          return autoSaveJson(null, graph);

        case 2:
        case "end":
          return _context2.stop();
      }
    }, _callee2);
  })), saveInterval); // 合并资源

  useEffect(() => {
    const globalAssets = _objectSpread(_objectSpread({}, assetsData), assets || {});

    window._globalAssets = globalAssets;
    setAssetsData(globalAssets);
  }, [assets]);
  useDebounceEffect(() => {
    restoreData();
  }, [data]); // 生成事件

  const _useHooks = useHooks({
    onRemoveLink,
    onRemoveNode,
    onAddLink,
    onSave
  }),
        actionFunMap = _useHooks.actionFunMap; // 画布事件响应


  const handlerActions = usePersistFn(action => {
    actionFunMap[action] && actionFunMap[action](currentCell, graph, {
      setVisible,
      setCurrentCell,
      setZoom,
      zoom,
      fullContainer: archWrapper.current,
      setIsFullScreen
    });
  }); // 拖拽进入创建环节

  const dragToCreateNode = node => {
    setCurrentCell(node);
    nextTick(() => setVisible(true));
  }; // 创建新节点


  const addNewNode = usePersistFn(nodeData => {
    const lane = graph === null || graph === void 0 ? void 0 : graph.getCellById(nodeData.preId);
    const node = graph === null || graph === void 0 ? void 0 : graph.createNode(createGraphNodeData(nodeData, {
      graph,
      assets: assetsData
    }));

    if (node && lane) {
      lane.addChild(node);
    }

    if (currentCell) {
      graph === null || graph === void 0 ? void 0 : graph.removeCell(currentCell);
      setCurrentCell(undefined);
    }
  }); // 修改节点信息

  const updateNode = usePersistFn(node => {
    const nodeData = node.data || {};
    const moduleType = nodeData.moduleType,
          name = nodeData.name,
          systemType = nodeData.systemType;
    const data = {
      image: `${(moduleType || '').toLowerCase()}Module`,
      bgImage: `${(systemType || '').toLowerCase()}System`
    };
    const grahpNode = graph === null || graph === void 0 ? void 0 : graph.getCellById(nodeData.id);
    grahpNode === null || grahpNode === void 0 ? void 0 : grahpNode.setData(_objectSpread(_objectSpread({}, nodeData), data), {
      silent: true
    });
    grahpNode === null || grahpNode === void 0 ? void 0 : grahpNode.attr({
      text: {
        text: getLabelText({
          label: name,
          maxTextLen: 20,
          maxLine: 2,
          placehoder: '...'
        })
      },
      itemTag: {
        xlinkHref: assetsData[data.image]
      },
      backgorund: {
        xlinkHref: assetsData[data.bgImage]
      }
    });
  }); // 创建或修改节点信息

  const submitNode = usePersistFn( /*#__PURE__*/function () {
    var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(node) {
      var flag, nodeData, isNew, ret;
      return regeneratorRuntime.wrap(function _callee3$(_context3) {
        while (1) switch (_context3.prev = _context3.next) {
          case 0:
            flag = false;
            nodeData = node.data || {};
            isNew = !nodeData.id;
            ret = undefined;

            if (!isNew) {
              _context3.next = 14;
              break;
            }

            if (!onCreateNode) {
              _context3.next = 11;
              break;
            }

            _context3.next = 8;
            return onCreateNode(nodeData);

          case 8:
            ret = _context3.sent;
            _context3.next = 12;
            break;

          case 11:
            flag = true;

          case 12:
            _context3.next = 21;
            break;

          case 14:
            if (!onUpdateNode) {
              _context3.next = 20;
              break;
            }

            _context3.next = 17;
            return onUpdateNode(nodeData);

          case 17:
            ret = _context3.sent;
            _context3.next = 21;
            break;

          case 20:
            flag = true;

          case 21:
            if (!flag && !!ret) {
              nodeData = ret;
              flag = true;
            } // 如果flag true 创建节点


            if (flag) {
              if (isNew) {
                addNewNode(nodeData);
              } else {
                updateNode(node);
              }
            }

            return _context3.abrupt("return", flag);

          case 24:
          case "end":
            return _context3.stop();
        }
      }, _callee3);
    }));

    return function (_x) {
      return _ref4.apply(this, arguments);
    };
  }());
  return /*#__PURE__*/React.createElement("div", {
    ref: archWrapper,
    className: "ra-arch-design"
  }, /*#__PURE__*/React.createElement(Spin, {
    spinning: initLoading,
    tip: "\u6570\u636E\u521D\u59CB\u5316\u4E2D\uFF0C\u8BF7\u7A0D\u5019..."
  }, /*#__PURE__*/React.createElement("div", {
    className: "ra-arch-aside"
  }, /*#__PURE__*/React.createElement(List, {
    onNodeCreate: dragToCreateNode,
    configs: moduleConfig,
    graph: graph,
    assets: assetsData
  })), /*#__PURE__*/React.createElement("div", {
    className: "ra-arch-content"
  }, /*#__PURE__*/React.createElement(CreateNode, {
    visible: visible,
    onClose: () => setVisible(false),
    node: currentCell,
    laneOptions: laneOptions,
    onSubmit: submitNode
  }), /*#__PURE__*/React.createElement("div", {
    className: "ra-arch-actions"
  }, /*#__PURE__*/React.createElement(ActionButtons, {
    onActions: handlerActions,
    isFullScreen: isFullScreen,
    canRedo: canRedo,
    canUndo: canUndo
  })), /*#__PURE__*/React.createElement("div", {
    className: "ra-arch-laneGroup"
  }, /*#__PURE__*/React.createElement(Lane, {
    setCurrentCell: setCurrentCell,
    data: graphData,
    onActions: handlerActions,
    onLoad: setGraph,
    assets: assetsData,
    zoom: zoom,
    isFullScreen: isFullScreen,
    setCanRedo: setCanRedo,
    setCanUndo: setCanUndo,
    onUndoOrRedo: onUndoOrRedo
  })))));
};

export default ArchDesign;